home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / contributed / waste / waste 1.3 / source / weutilities.c < prev   
Encoding:
C/C++ Source or Header  |  2000-06-23  |  3.9 KB  |  211 lines

  1. /*
  2.  *    WEUtilities.c
  3.  *
  4.  *    WASTE PROJECT
  5.  *  Miscellaneous General-Purpose Utilities
  6.  *
  7.  *  Copyright (c) 1993-1998 Marco Piovanelli
  8.  *    All Rights Reserved
  9.  *
  10.  *  C port by Dan Crevier
  11.  *
  12.  */
  13.  
  14.  
  15. #include "WASTEIntf.h"
  16.  
  17. pascal Boolean _WEBlockCmp ( const void * block1, const void * block2, Size blockSize )
  18. {
  19.     const UInt8 * p1 = ( const UInt8 * ) block1 ;
  20.     const UInt8 * p2 = ( const UInt8 * ) block2 ;
  21.  
  22.     for ( ; blockSize > 0 ; blockSize -- )
  23.     {
  24.         if ( * p1 ++ != * p2 ++ ) return false ;
  25.     }
  26.  
  27.     return true ;
  28. }
  29.  
  30. pascal void _WEBlockClr ( void * block, Size blockSize )
  31. {
  32.     UInt8 * p = ( UInt8 * ) block ;
  33.  
  34.     if ( blockSize >= 16 )
  35.     {
  36.         //    advance block pointer to next even address
  37.         if ( ( UInt32 ) p & 1 )
  38.         {
  39.             * p ++ = 0 ;
  40.             blockSize -- ;
  41.         }
  42.  
  43.         //    advance block pointer to next address divisible by four
  44.         if ( ( UInt32 ) p & 2 )
  45.         {
  46.             * ( UInt16 * ) p = 0 ;
  47.             p += 2 ;
  48.             blockSize -= 2 ;
  49.         }
  50.  
  51.         //    clear 16-byte blocks
  52.         for ( ; blockSize >= 16 ; blockSize -= 16 )
  53.         {
  54.             * ( ( UInt32 * ) p     ) = 0 ;
  55.             * ( ( UInt32 * ) p + 1 ) = 0 ;
  56.             * ( ( UInt32 * ) p + 2 ) = 0 ;
  57.             * ( ( UInt32 * ) p + 3 ) = 0 ;
  58.             p += 16 ;
  59.         }
  60.     }
  61.  
  62.     //    clear remaining bytes
  63.     for ( ; blockSize > 0 ; blockSize -- )
  64.     {
  65.         * p ++ = 0 ;
  66.     }
  67. }
  68.  
  69. pascal void _WEForgetHandle ( Handle * h )
  70. {
  71.     Handle theHandle ;
  72.  
  73.     if ( ( theHandle = * h ) != nil )
  74.     {
  75.         * h = nil ;
  76.         DisposeHandle ( theHandle ) ;
  77.     }
  78. }
  79.  
  80. pascal Boolean _WESetHandleLock ( Handle h, Boolean lock )
  81. {
  82.     Boolean oldLock = ( HGetState ( h ) & ( 1 << 7 ) ) != 0 ;
  83.  
  84.     if ( lock != oldLock )
  85.     {
  86.         if ( lock )
  87.         {
  88.             HLock ( h ) ;
  89.         }
  90.         else
  91.         {
  92.             HUnlock ( h ) ;
  93.         }
  94.     }
  95.  
  96.     return oldLock ;
  97. }
  98.  
  99. pascal void _WEReorder ( SInt32 * a, SInt32 * b )
  100. {
  101.     if ( * a > * b )
  102.     {
  103.         SInt32 temp = * a ;
  104.         * a = * b ;
  105.         * b = temp ;
  106.     }
  107. }
  108.  
  109. pascal OSErr _WEAllocate ( Size blockSize, UInt32 allocFlags, Handle * h )
  110. {
  111.     // Allocate a new relocatable block.
  112.     // AllocFlags may specify whether the block should be cleared and whether
  113.     // temporary memory should be used.
  114.  
  115.     Handle theHandle = nil ;
  116.     OSErr err ;
  117.  
  118.     // if kAllocTemp is specified, try tapping temporary memory
  119.     if ( allocFlags & kAllocTemp )
  120.     {
  121.         theHandle = TempNewHandle ( blockSize, & err ) ;
  122.     }
  123.  
  124.     // if kAllocTemp isn't specified, or TempNewHandle failed, try with current heap
  125.     if ( theHandle == nil )
  126.     {
  127.         theHandle = NewHandle ( blockSize ) ;
  128.         err = MemError ( ) ;
  129.     }
  130.  
  131.     // if kAllocClear is specified, zero the block
  132.     if ( ( allocFlags & kAllocClear ) && ( theHandle != nil ) )
  133.     {
  134.         _WEBlockClr ( * theHandle, blockSize ) ;
  135.     }
  136.  
  137.     * h = theHandle ;
  138.     return err ;
  139. }
  140.  
  141. pascal OSErr _WESplice ( Handle h, const void * blockPtr, SInt32 blockSize, SInt32 offset )
  142. {
  143.     SInt32 oldSize, newSize ;
  144.     OSErr err ;
  145.  
  146.     //    get handle size
  147.     oldSize = GetHandleSize ( h ) ;
  148.  
  149.     //    calculate new size
  150.     newSize = oldSize + blockSize ;
  151.  
  152.     if ( blockSize < 0 )
  153.     {
  154.         //    negative blockSize means we must remove a portion of the block
  155.         //    offset == -1 means remove trailing portion
  156.         if ( offset == -1 )
  157.         {
  158.             offset = newSize ;
  159.         }
  160.  
  161.         //    sanity checks
  162.         err = paramErr ;
  163.         if ( ( offset < 0 ) || ( offset > newSize ) )
  164.         {
  165.             goto cleanup ;
  166.         }
  167.  
  168.         //    compact the handle
  169.         BlockMoveData ( * h + ( offset - blockSize ), * h + offset, newSize - offset ) ;
  170.     }
  171.  
  172.     //    resize the handle
  173.     SetHandleSize ( h, newSize ) ;
  174.     if ( ( err = MemError ( ) ) != noErr )
  175.     {
  176.         goto cleanup ;
  177.     }
  178.  
  179.     if ( blockSize > 0 )
  180.     {
  181.         //    positive blockSize means make room within the handle
  182.         //    offset == -1 means append new portion at the end
  183.         if ( offset == -1 )
  184.         {
  185.             offset = oldSize ;
  186.         }
  187.  
  188.         //    sanity checks
  189.         err = paramErr ;
  190.         if ( ( offset < 0 ) || ( offset > oldSize ) )
  191.         {
  192.             goto cleanup ;
  193.         }
  194.  
  195.         //    make some room at offset
  196.         BlockMoveData ( * h + offset, * h + offset + blockSize, oldSize - offset ) ;
  197.  
  198.         //    insert blockPtr into gap (unless blockPtr == nil)
  199.         if ( blockPtr != nil )
  200.         {
  201.             BlockMoveData ( blockPtr, * h + offset, blockSize ) ;
  202.         }
  203.     }
  204.  
  205.     //    clear result code
  206.     err = noErr ;
  207.  
  208. cleanup :
  209.     return err ;
  210. }
  211.